home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Games
/
MAME
/
src
/
vidhrdw
/
sega.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-08-20
|
7KB
|
256 lines
/***************************************************************************
vidhrdw.c
Generic functions used by the Sega Vector games
***************************************************************************/
/*
* History:
*
* 97???? Converted Al Kossow's G80 sources. LBO
* 970807 Scaling support and dynamic sin/cos tables. ASG
* 980124 Suport for antialiasing. .ac
* 980203 cleaned up and interfaced to generic vector routines. BW
*
* TODO: use floating point math instead of fixed point.
*/
#include "driver.h"
#include "avgdvg.h"
#include "vector.h"
#include <math.h>
#define VEC_SHIFT 15 /* do not use a higher value. Values will overflow */
static int width, height, cent_x, cent_y, min_x, min_y, max_x, max_y;
static long *sinTable, *cosTable;
static int intensity;
void sega_generate_vector_list (void)
{
int deltax, deltay;
int currentX, currentY;
int vectorIndex;
int symbolIndex;
int rotate, scale;
int attrib;
int angle, length;
int color;
int draw;
vector_clear_list();
symbolIndex = 0; /* Reset vector PC to 0 */
/*
* walk the symbol list until 'last symbol' set
*/
do {
draw = vectorram[symbolIndex++];
if (draw & 1) /* if symbol active */
{
currentX = vectorram[symbolIndex + 0] | (vectorram[symbolIndex + 1] << 8);
currentY = vectorram[symbolIndex + 2] | (vectorram[symbolIndex + 3] << 8);
vectorIndex = vectorram[symbolIndex + 4] | (vectorram[symbolIndex + 5] << 8);
rotate = vectorram[symbolIndex + 6] | (vectorram[symbolIndex + 7] << 8);
scale = vectorram[symbolIndex + 8];
currentX = ((currentX & 0x7ff) - min_x) << VEC_SHIFT;
currentY = (max_y - (currentY & 0x7ff)) << VEC_SHIFT;
vector_add_point ( currentX, currentY, 0, 0);
vectorIndex &= 0xfff;
/* walk the vector list until 'last vector' bit */
/* is set in attributes */
do
{
attrib = vectorram[vectorIndex + 0];
length = vectorram[vectorIndex + 1];
angle = vectorram[vectorIndex + 2] | (vectorram[vectorIndex + 3] << 8);
vectorIndex += 4;
/* calculate deltas based on len, angle(s), and scale factor */
angle = (angle + rotate) & 0x3ff;
deltax = sinTable[angle] * scale * length;
deltay = cosTable[angle] * scale * length;
currentX += deltax >> 7;
currentY -= deltay >> 7;
color = attrib & 0x7e;
if ((attrib & 1) && color)
{
if (translucency)
intensity = 0xa0; /* leave room for translucency */
else
intensity = 0xff;
}
else
intensity = 0;
vector_add_point ( currentX, currentY, color, intensity );
} while (!(attrib & 0x80));
}
symbolIndex += 9;
if (symbolIndex >= vectorram_size)
break;
} while (!(draw & 0x80));
}
/***************************************************************************
The Sega vector games don't have a color PROM, it uses RGB values for the
vector guns.
This routine sets up the color tables to simulate it.
***************************************************************************/
void sega_init_colors (unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
{
int i,r,g,b;
/* Bits are-> Red: 6&5 (0x60), Green: 4&3 (0x18), Blue: 2&1 (0x06) */
for (i=0; i<128; i+=2)
{
palette[3*i ] = 85 * ((i>>5)&0x3);
palette[3*i+1] = 85 * ((i>>3)&0x3);
palette[3*i+2] = 85 * ((i>>1)&0x3);
/* Set the color table */
colortable[i] = i;
}
/*
* Fill in the holes with good anti-aliasing colors. This is a very good
* range of colors based on the previous palette entries. .ac JAN2498
*/
i=1;
for (r=0; r<=6; r++)
{
for (g=0; g<=6; g++)
{
for (b=0; b<=6; b++)
{
if (!((r|g|b)&0x1) ) continue;
if ((g==5 || g==6) && (b==1 || b==2 || r==1 || r==2)) continue;
if ((g==3 || g==4) && (b==1 || r==1 )) continue;
if ((b==6 || r==6) && (g==1 || g==2 )) continue;
if ((r==5) && (b==1) ) continue;
if ((b==5) && (r==1) ) continue;
palette[3*i ] = (255*r) / 6;
palette[3*i+1] = (255*g) / 6;
palette[3*i+2] = (255*b) / 6;
colortable[i] = i;
if (i < 128)
i+=2;
else
i++;
}
}
}
/* There are still 4 colors left, just going to put some grays in. */
for (i=252; i<=255; i++)
{
palette[3*i ] =
palette[3*i+1] =
palette[3*i+2] = 107 + (42*(i-252));
}
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
int sega_vh_start (void)
{
int i;
if (vectorram_size == 0)
return 1;
min_x =Machine->drv->visible_area.min_x;
min_y =Machine->drv->visible_area.min_y;
max_x =Machine->drv->visible_area.max_x;
max_y =Machine->drv->visible_area.max_y;
width =max_x-min_x;
height=max_y-min_y;
cent_x=(max_x+min_x)/2;
cent_y=(max_y+min_y)/2;
vector_set_shift (VEC_SHIFT);
/* allocate memory for the sine and cosine lookup tables ASG 080697 */
sinTable = malloc (0x400 * sizeof (long));
if (!sinTable)
return 1;
cosTable = malloc (0x400 * sizeof (long));
if (!cosTable)
{
free (sinTable);
return 1;
}
/* generate the sine/cosine lookup tables */
for (i = 0; i < 0x400; i++)
{
double angle = ((2. * PI) / (double)0x400) * (double)i;
double temp;
temp = sin (angle);
if (temp < 0)
sinTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) - 0.5);
else
sinTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) + 0.5);
temp = cos (angle);
if (temp < 0)
cosTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) - 0.5);
else
cosTable[i] = (long)(temp * (double)(1 << VEC_SHIFT) + 0.5);
}
return vector_vh_start();
}
/***************************************************************************
Stop the video hardware emulation.
***************************************************************************/
void sega_vh_stop (void)
{
if (sinTable)
free (sinTable);
sinTable = NULL;
if (cosTable)
free (cosTable);
cosTable = NULL;
vector_vh_stop();
}
/***************************************************************************
Draw the game screen in the given osd_bitmap.
Do NOT call osd_update_display() from this function, it will be called by
the main emulation engine.
***************************************************************************/
void sega_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
{
sega_generate_vector_list();
vector_vh_update(bitmap,full_refresh);
}